/*
 * @Author: FamiliennameistChow nameistchow@hotmail.com
 * @Date: 2023-10-31 23:09:30
 * @LastEditors: FamiliennameistChow nameistchow@hotmail.com
 * @LastEditTime: 2023-11-07 22:06:17
 * @FilePath: /pcl_tutorials/PointCloudView.hpp
 * @Description: 
 * 
 * Copyright (c) 2023 by FamiliennameistChow, All Rights Reserved. 
 */
#ifndef _POINT_CLOUD_VIEW_H_
#define _POINT_CLOUD_VIEW_H_

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/colors.h>

typedef pcl::PointXYZI PointType;

class PointCloudView
{

public:
    PointCloudView(/* args */){};
    ~PointCloudView(){};

    static void simpleView(pcl::PointCloud<PointType>::Ptr cloud){
        boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer("3D Viewer"));

        viewer->setBackgroundColor(0, 0, 0); // 黑色背景
        viewer->addCoordinateSystem(0.1);
        //viewer->initCameraParameters();

        pcl::visualization::PointCloudColorHandlerCustom<PointType> single_color(cloud, 255, 255, 255); // 白色点
        viewer->addPointCloud<PointType>(cloud, single_color, "cloud");
        viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "cloud");

        while (!viewer->wasStopped()){
            viewer->spinOnce();
        }
    }


	// ------------------------------------------------------------------
	// ---  在同一个窗口使用不同颜色显示多幅点云
	// ---  show multi clouds in one window with differnt colors
	// ------------------------------------------------------------------
    static void cloudsVecView(std::vector<pcl::PointCloud<PointType>::Ptr > cloud_vector){

		boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
		viewer->setBackgroundColor(0, 0, 0);
		viewer->addCoordinateSystem(0.1);

		for (size_t i = 0; i < cloud_vector.size(); i++){
			Eigen::Vector3i rst = pcl::GlasbeyLUT::at(i).getRGBVector3i();
			pcl::visualization::PointCloudColorHandlerCustom<PointType> single_color(cloud_vector[i], rst[0], rst[1], rst[2]);
			viewer->addPointCloud<PointType>(cloud_vector[i], single_color, "sample cloud" + std::to_string(i));
			viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud" + std::to_string(i));
		}

		while (!viewer->wasStopped()){
			viewer->spinOnce();
		}

    }

	static pcl::visualization::PCLVisualizer::Ptr rgbPointVis(pcl::PointCloud<pcl::PointXYZRGBA>::ConstPtr cloud){

		pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
		pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGBA> rgb(cloud);
		viewer->setBackgroundColor(0, 0, 0);
		viewer->addPointCloud<pcl::PointXYZRGBA>(cloud, "biansu cloud");
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "biansu cloud"); 
		viewer->addCoordinateSystem(1.0);
		return viewer;
	}

	static pcl::visualization::PCLVisualizer::Ptr VisPointAndNormal(pcl::PointCloud<PointType>::ConstPtr cloud,
		pcl::PointCloud<pcl::Normal>::ConstPtr normals)
	{

		pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
		viewer->setBackgroundColor(0, 0, 0);
		viewer->addText("normal", 10, 10, "text");
		pcl::visualization::PointCloudColorHandlerCustom<PointType> single_color(cloud, 0, 225, 0);
		viewer->addCoordinateSystem(1.0);
		viewer->addPointCloud<PointType>(cloud, single_color, "sample cloud");
		//添加需要显示的点云法向。cloud为原始点云模型，normal为法向信息，10表示需要显示法向的点云间隔，即每10个点显示一次法向，0.5s表示法向长度。
		viewer->addPointCloudNormals<PointType, pcl::Normal>(cloud, normals, 10, 0.5, "normals");
		//设置点云大小
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "sample cloud");
		return viewer;
	}


	static pcl::visualization::PCLVisualizer::Ptr visPointWithIntensity(pcl::PointCloud<PointType>::ConstPtr cloud)
	{

		pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));
		viewer->setBackgroundColor(0, 0, 0);
		pcl::visualization::PointCloudColorHandlerGenericField<PointType> single_color(cloud, "intensity");

		viewer->addPointCloud<PointType>(cloud, single_color, "sample cloud");
		viewer->addCoordinateSystem(0.5);
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "sample cloud");
		return viewer;
	}

    //https://blog.csdn.net/weixin_44368569/article/details/130405588
    static void comparedCloudsView(pcl::PointCloud<PointType>::Ptr cloud1, pcl::PointCloud<PointType>::Ptr cloud2){
        boost::shared_ptr<pcl::visualization::PCLVisualizer> viewer (new pcl::visualization::PCLVisualizer("3D Viewer"));
        
		int v1(0);
        viewer->createViewPort(0.0, 0.0, 0.5, 1.0, v1);
        viewer->setBackgroundColor(0, 0, 0, v1);
		pcl::visualization::PointCloudColorHandlerCustom<PointType> single_color(cloud1, 255, 255, 255);
		viewer->addPointCloud<PointType>(cloud1, single_color, "cloud1", v1);
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud1", v1);

		int v2(1);
		viewer->createViewPort(0.5, 0.0, 1.0, 1.0, v2);
		viewer->setBackgroundColor(0, 0, 0, v2);
		pcl::visualization::PointCloudColorHandlerCustom<PointType> single_color2(cloud2, 255, 255, 255);
		viewer->addPointCloud<PointType>(cloud2, single_color2, "cloud2", v2);
		viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 3, "cloud2", v2);

		viewer->addCoordinateSystem(5.0);

        while (!viewer->wasStopped()){
            viewer->spinOnce();
        }
    }
};


#endif